// Copyright Epic Games, Inc. All Rights Reserved.

#include "LyraPawnExtensionComponent.h"

// 包含必要的头文件
#include "AbilitySystem/LyraAbilitySystemComponent.h"  // Lyra能力系统组件
#include "Components/GameFrameworkComponentDelegates.h" // 游戏框架组件委托
#include "Components/GameFrameworkComponentManager.h"   // 游戏框架组件管理器
#include "GameFramework/Controller.h"                  // 控制器
#include "GameFramework/Pawn.h"                        // Pawn
#include "LyraGameplayTags.h"                          // Lyra游戏标签
#include "LyraLogChannels.h"                           // Lyra日志通道
#include "LyraPawnData.h"                              // Lyra pawn数据
#include "Net/UnrealNetwork.h"                         // 网络复制

#include UE_INLINE_GENERATED_CPP_BY_NAME(LyraPawnExtensionComponent)  // 内联生成的C++代码

class FLifetimeProperty;  // 生命周期属性
class UActorComponent;    // 角色组件

// 定义功能名称
const FName ULyraPawnExtensionComponent::NAME_ActorFeatureName("PawnExtension");

// 构造函数
ULyraPawnExtensionComponent::ULyraPawnExtensionComponent(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
    // 禁用组件tick
	PrimaryComponentTick.bStartWithTickEnabled = false;
	PrimaryComponentTick.bCanEverTick = false;

    // 默认启用复制
	SetIsReplicatedByDefault(true);

    // 初始化指针为null
	PawnData = nullptr;
	AbilitySystemComponent = nullptr;
}

// 设置网络复制属性
void ULyraPawnExtensionComponent::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
	Super::GetLifetimeReplicatedProps(OutLifetimeProps);

    // 复制PawnData属性
	DOREPLIFETIME(ULyraPawnExtensionComponent, PawnData);
}

// 组件注册时调用
void ULyraPawnExtensionComponent::OnRegister()
{
	Super::OnRegister();

    // 确保组件只添加到Pawn actor上
	const APawn* Pawn = GetPawn<APawn>();
	ensureAlwaysMsgf((Pawn != nullptr), TEXT("LyraPawnExtensionComponent on [%s] can only be added to Pawn actors."), *GetNameSafe(GetOwner()));

    // 确保每个Pawn只有一个扩展组件
	TArray<UActorComponent*> PawnExtensionComponents;
	Pawn->GetComponents(ULyraPawnExtensionComponent::StaticClass(), PawnExtensionComponents);
	ensureAlwaysMsgf((PawnExtensionComponents.Num() == 1), TEXT("Only one LyraPawnExtensionComponent should exist on [%s]."), *GetNameSafe(GetOwner()));

    // 注册到初始化状态系统
	RegisterInitStateFeature();
}

// 游戏开始时调用
void ULyraPawnExtensionComponent::BeginPlay()
{
	Super::BeginPlay();

    // 监听所有功能的改变
	BindOnActorInitStateChanged(NAME_None, FGameplayTag(), false);
	
    // 通知状态管理器我们已经生成，然后尝试其余的默认初始化
	ensure(TryToChangeInitState(LyraGameplayTags::InitState_Spawned));
	CheckDefaultInitialization();
}

// 游戏结束时调用
void ULyraPawnExtensionComponent::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
    // 清理能力系统
	UninitializeAbilitySystem();
    // 取消注册初始化状态功能
	UnregisterInitStateFeature();

	Super::EndPlay(EndPlayReason);
}

// 设置Pawn数据
void ULyraPawnExtensionComponent::SetPawnData(const ULyraPawnData* InPawnData)
{
	check(InPawnData);  // 确保数据有效

	APawn* Pawn = GetPawnChecked<APawn>();

    // 只在服务端执行
	if (Pawn->GetLocalRole() != ROLE_Authority)
	{
		return;
	}

    // 如果已经有PawnData，记录错误
	if (PawnData)
	{
		UE_LOG(LogLyra, Error, TEXT("Trying to set PawnData [%s] on pawn [%s] that already has valid PawnData [%s]."), *GetNameSafe(InPawnData), *GetNameSafe(Pawn), *GetNameSafe(PawnData));
		return;
	}

	PawnData = InPawnData;  // 设置Pawn数据

    // 强制网络更新
	Pawn->ForceNetUpdate();

    // 检查初始化
	CheckDefaultInitialization();
}

// 当PawnData在客户端复制时调用
void ULyraPawnExtensionComponent::OnRep_PawnData()
{
	CheckDefaultInitialization();
}

// 初始化能力系统
void ULyraPawnExtensionComponent::InitializeAbilitySystem(ULyraAbilitySystemComponent* InASC, AActor* InOwnerActor)
{
	check(InASC);
	check(InOwnerActor);

    // 如果能力系统组件没有改变，直接返回
	if (AbilitySystemComponent == InASC)
	{
		return;
	}

    // 如果已有能力系统组件，先清理
	if (AbilitySystemComponent)
	{
		UninitializeAbilitySystem();
	}

	APawn* Pawn = GetPawnChecked<APawn>();
	AActor* ExistingAvatar = InASC->GetAvatarActor();

	UE_LOG(LogLyra, Verbose, TEXT("Setting up ASC [%s] on pawn [%s] owner [%s], existing [%s] "), *GetNameSafe(InASC), *GetNameSafe(Pawn), *GetNameSafe(InOwnerActor), *GetNameSafe(ExistingAvatar));

    // 如果已经有其他pawn作为ASC的化身，需要踢出它
	if ((ExistingAvatar != nullptr) && (ExistingAvatar != Pawn))
	{
		UE_LOG(LogLyra, Log, TEXT("Existing avatar (authority=%d)"), ExistingAvatar->HasAuthority() ? 1 : 0);

        // 确保现有化身没有权限（只在客户端发生）
		ensure(!ExistingAvatar->HasAuthority());

        // 取消初始化其他pawn的能力系统
		if (ULyraPawnExtensionComponent* OtherExtensionComponent = FindPawnExtensionComponent(ExistingAvatar))
		{
			OtherExtensionComponent->UninitializeAbilitySystem();
		}
	}

    // 设置新的能力系统组件
	AbilitySystemComponent = InASC;
	AbilitySystemComponent->InitAbilityActorInfo(InOwnerActor, Pawn);

    // 设置标签关系映射
	if (ensure(PawnData))
	{
		InASC->SetTagRelationshipMapping(PawnData->TagRelationshipMapping);
	}

    // 广播初始化完成
	OnAbilitySystemInitialized.Broadcast();
}

// 取消初始化能力系统
void ULyraPawnExtensionComponent::UninitializeAbilitySystem()
{
	if (!AbilitySystemComponent)
	{
		return;
	}

    // 如果我们还是化身actor，取消初始化ASC
	if (AbilitySystemComponent->GetAvatarActor() == GetOwner())
	{
        // 忽略死亡后仍然存在的能力类型
		FGameplayTagContainer AbilityTypesToIgnore;
		AbilityTypesToIgnore.AddTag(LyraGameplayTags::Ability_Behavior_SurvivesDeath);

        // 取消能力、清除输入、移除游戏提示
		AbilitySystemComponent->CancelAbilities(nullptr, &AbilityTypesToIgnore);
		AbilitySystemComponent->ClearAbilityInput();
		AbilitySystemComponent->RemoveAllGameplayCues();

        // 设置化身actor为null
		if (AbilitySystemComponent->GetOwnerActor() != nullptr)
		{
			AbilitySystemComponent->SetAvatarActor(nullptr);
		}
		else
		{
            // 如果ASC没有有效的拥有者，清除所有actor信息
			AbilitySystemComponent->ClearActorInfo();
		}

        // 广播取消初始化
		OnAbilitySystemUninitialized.Broadcast();
	}

	AbilitySystemComponent = nullptr;
}

// 处理控制器改变
void ULyraPawnExtensionComponent::HandleControllerChanged()
{
    // 如果我们是ASC的化身actor
	if (AbilitySystemComponent && (AbilitySystemComponent->GetAvatarActor() == GetPawnChecked<APawn>()))
	{
		ensure(AbilitySystemComponent->AbilityActorInfo->OwnerActor == AbilitySystemComponent->GetOwnerActor());
        
        // 如果拥有者actor为null，取消初始化
		if (AbilitySystemComponent->GetOwnerActor() == nullptr)
		{
			UninitializeAbilitySystem();
		}
		else
		{
            // 否则刷新能力actor信息
			AbilitySystemComponent->RefreshAbilityActorInfo();
		}
	}

	CheckDefaultInitialization();
}

// 处理玩家状态复制
void ULyraPawnExtensionComponent::HandlePlayerStateReplicated()
{
	CheckDefaultInitialization();
}

// 设置玩家输入组件
void ULyraPawnExtensionComponent::SetupPlayerInputComponent()
{
	CheckDefaultInitialization();
}

// 检查默认初始化
void ULyraPawnExtensionComponent::CheckDefaultInitialization()
{
    // 在检查进度之前，尝试推进我们可能依赖的任何其他功能
	CheckDefaultInitializationForImplementers();

    // 定义初始化状态链
	static const TArray<FGameplayTag> StateChain = { LyraGameplayTags::InitState_Spawned, LyraGameplayTags::InitState_DataAvailable, LyraGameplayTags::InitState_DataInitialized, LyraGameplayTags::InitState_GameplayReady };

    // 尝试从生成状态推进到游戏准备状态
	ContinueInitStateChain(StateChain);
}

// 检查是否可以改变初始化状态
bool ULyraPawnExtensionComponent::CanChangeInitState(UGameFrameworkComponentManager* Manager, FGameplayTag CurrentState, FGameplayTag DesiredState) const
{
	check(Manager);

	APawn* Pawn = GetPawn<APawn>();
    
    // 从无状态到生成状态
	if (!CurrentState.IsValid() && DesiredState == LyraGameplayTags::InitState_Spawned)
	{
        // 只要在有效的pawn上，就视为已生成
		if (Pawn)
		{
			return true;
		}
	}
    
    // 从生成状态到数据可用状态
	if (CurrentState == LyraGameplayTags::InitState_Spawned && DesiredState == LyraGameplayTags::InitState_DataAvailable)
	{
        // 需要Pawn数据
		if (!PawnData)
		{
			return false;
		}

		const bool bHasAuthority = Pawn->HasAuthority();
		const bool bIsLocallyControlled = Pawn->IsLocallyControlled();

        // 对于有权限或本地控制的pawn
		if (bHasAuthority || bIsLocallyControlled)
		{
            // 检查是否被控制器拥有
			if (!GetController<AController>())
			{
				return false;
			}
		}

		return true;
	}
    
    // 从数据可用状态到数据初始化状态
	else if (CurrentState == LyraGameplayTags::InitState_DataAvailable && DesiredState == LyraGameplayTags::InitState_DataInitialized)
	{
        // 当所有功能都达到数据可用状态时，转换到初始化状态
		return Manager->HaveAllFeaturesReachedInitState(Pawn, LyraGameplayTags::InitState_DataAvailable);
	}
    
    // 从数据初始化状态到游戏准备状态
	else if (CurrentState == LyraGameplayTags::InitState_DataInitialized && DesiredState == LyraGameplayTags::InitState_GameplayReady)
	{
		return true;
	}

	return false;
}

// 处理初始化状态改变
void ULyraPawnExtensionComponent::HandleChangeInitState(UGameFrameworkComponentManager* Manager, FGameplayTag CurrentState, FGameplayTag DesiredState)
{
    // 数据初始化状态的处理目前由监听此状态改变的其他组件处理
	if (DesiredState == LyraGameplayTags::InitState_DataInitialized)
	{
	}
}

// 当其他actor的初始化状态改变时调用
void ULyraPawnExtensionComponent::OnActorInitStateChanged(const FActorInitStateChangedParams& Params)
{
    // 如果其他功能现在处于DataAvailable状态，检查我们是否应该转换到DataInitialized
	if (Params.FeatureName != NAME_ActorFeatureName)
	{
		if (Params.FeatureState == LyraGameplayTags::InitState_DataAvailable)
		{
			CheckDefaultInitialization();
		}
	}
}

// 注册能力系统初始化委托并立即调用（如果已初始化）
void ULyraPawnExtensionComponent::OnAbilitySystemInitialized_RegisterAndCall(FSimpleMulticastDelegate::FDelegate Delegate)
{
    // 如果委托尚未绑定，添加它
	if (!OnAbilitySystemInitialized.IsBoundToObject(Delegate.GetUObject()))
	{
		OnAbilitySystemInitialized.Add(Delegate);
	}

    // 如果能力系统已初始化，立即执行委托
	if (AbilitySystemComponent)
	{
		Delegate.Execute();
	}
}

// 注册能力系统取消初始化委托
void ULyraPawnExtensionComponent::OnAbilitySystemUninitialized_Register(FSimpleMulticastDelegate::FDelegate Delegate)
{
    // 如果委托尚未绑定，添加它
	if (!OnAbilitySystemUninitialized.IsBoundToObject(Delegate.GetUObject()))
	{
		OnAbilitySystemUninitialized.Add(Delegate);
	}
}